#ifndef NT_INCLUDED
#define NT_INCLUDED
#define CurrentProcess ((HANDLE)-1)
typedef struct _ANSI_STRING
{
    USHORT Length;
    USHORT MaximumLength;
    PCHAR Buffer;
} ANSI_STRING,  *PANSI_STRING;
typedef struct _UNICODE_STRING
{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR Buffer;
} UNICODE_STRING,  *PUNICODE_STRING;

typedef struct _OBJECT_ATTRIBUTES
{
    ULONG Length;
    HANDLE RootDirectory;
    PUNICODE_STRING ObjectName;
    ULONG Attributes;
    PVOID SecurityDescriptor;
    PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES,  *POBJECT_ATTRIBUTES;
#define initoa(oa,on) (oa).Length=sizeof(OBJECT_ATTRIBUTES),(oa).RootDirectory=0,(oa).ObjectName=(on),(oa).Attributes=0,(oa).SecurityDescriptor=0,(oa).SecurityQualityOfService=0
#define makeoa(on) {sizeof(OBJECT_ATTRIBUTES),0,on,0,0,0}
typedef struct _IO_STATUS_BLOCK
{
    union
    {
        NTSTATUS Status;
        PVOID Pointer;
    };
    ULONG_PTR Information;
}

//-------------------------------------------------------------------------

IO_STATUS_BLOCK,  *PIO_STATUS_BLOCK;
#define FILE_SUPERSEDE                    0x00000000
#define FILE_OPEN                               0x00000001
#define FILE_CREATE                          0x00000002
#define FILE_OPEN_IF                          0x00000003
#define FILE_OVERWRITE                    0x00000004
#define FILE_OVERWRITE_IF               0x00000005
#define FILE_SYNCHRONOUS_IO_ALERT 0x0000001
#define FILE_SYNCHRONOUS_IO_NONALERT 0x0000002
#define FILE_NON_DIRECTORY_FILE 0x0000004
#define FILE_CREATE_TREE_CONNECTION 0x0000008

#define FILE_COMPLETE_IF_OPLOCKED 0x0000010
#define FILE_NO_EA_KNOWLEDGE 0x0000020
#define FILE_OPEN_FOR_RECOVERY 0x0000040
#define FILE_RANDOM_ACCESS 0x0000080

#define FILE_DELETE_ON_CLOSE 0x0000100
#define FILE_OPEN_BY_FILE_ID 0x0000200
#define FILE_OPEN_FOR_BACKUP_INTENT 0x0000400
#define FILE_NO_COMPRESSION 0x0000800

#define FILE_RESERVE_OPFILTER 0x0010000
#define FILE_OPEN_REPARSE_POINT 0x0020000
#define FILE_OPEN_NO_RECALL 0x0040000
#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x0080000

#define FILE_COPY_STRUCTURED_STORAGE 0x0000004
#define FILE_STRUCTURED_STORAGE 0x0000044

#define FILE_VALID_OPTION_FLAGS 0x00fffff
#define FILE_VALID_PIPE_OPTION_FLAGS 0x0000003
#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x0000003
#define FILE_VALID_SET_FLAGS 0x00000036
typedef struct _FILE_FULL_EA_INFORMATION
{
    ULONG NextEntryOffset;
    UCHAR Flags;
    UCHAR EaNameLength;
    USHORT EaValueLength;
    CHAR EaName[1];
} FILE_FULL_EA_INFORMATION,  *PFILE_FULL_EA_INFORMATION;
typedef enum _SECTION_INHERIT
{
    ViewShare = 1, ViewUnmap = 2
} SECTION_INHERIT;
typedef VOID(NTAPI *PIO_APC_ROUTINE)(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved);

typedef struct _CLIENT_ID
{
    HANDLE UniqueProcess;
    HANDLE UniqueThread;
} CLIENT_ID;
typedef CLIENT_ID *PCLIENT_ID;
typedef enum _MEMORY_INFORMATION_CLASS
{
    MemoryBasicInformation, MemoryWorkingSetList, MemorySectionName, MemoryBasicVlmInformation
} MEMORY_INFORMATION_CLASS;

typedef struct _LDR_DATA_TABLE_ENTRY
{
    LIST_ENTRY InLoadOrderLinks;
    LIST_ENTRY InMemoryOrderLinks;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID DllBase;
    PVOID EntryPoint;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    ULONG Flags;
    WORD LoadCount;
    WORD TlsIndex;
    union
    {
        LIST_ENTRY HashLinks;
        struct 
        {
            PVOID SectionPointer;
            ULONG CheckSum;
        };
    };
    union
    {
        ULONG TimeDateStamp;
        PVOID LoadedImports;
    };
    void *EntryPointActivationContext;
    PVOID PatchInformation;
    LIST_ENTRY ForwarderLinks;
    LIST_ENTRY ServiceTagLinks;
    LIST_ENTRY StaticLinks;
}LDR_DATA_TABLE_ENTRY,  *PLDR_DATA_TABLE_ENTRY;

typedef struct _PEB_LDR_DATA
{
    ULONG Length;
    UCHAR Initialized;
    PVOID SsHandle;
    LIST_ENTRY InLoadOrderModuleList;
    LIST_ENTRY InMemoryOrderModuleList;
    LIST_ENTRY InInitializationOrderModuleList;
    PVOID EntryInProgress;
} PEB_LDR_DATA,  *PPEB_LDR_DATA;
typedef struct _CURDIR
{
    UNICODE_STRING DosPath;
    PVOID Handle;
} CURDIR,  *PCURDIR;
typedef struct _RTL_DRIVE_LETTER_CURDIR
{
    WORD Flags;
    WORD Length;
    ULONG TimeStamp;
    ANSI_STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR,  *PRTL_DRIVE_LETTER_CURDIR;
typedef struct _RTL_USER_PROCESS_PARAMETERS
{
    ULONG MaximumLength;
    ULONG Length;
    ULONG Flags;
    ULONG DebugFlags;
    PVOID ConsoleHandle;
    ULONG ConsoleFlags;
    PVOID StandardInput;
    PVOID StandardOutput;
    PVOID StandardError;
    CURDIR CurrentDirectory;
    UNICODE_STRING DllPath;
    UNICODE_STRING ImagePathName;
    UNICODE_STRING CommandLine;
    PVOID Environment;
    ULONG StartingX;
    ULONG StartingY;
    ULONG CountX;
    ULONG CountY;
    ULONG CountCharsX;
    ULONG CountCharsY;
    ULONG FillAttribute;
    ULONG WindowFlags;
    ULONG ShowWindowFlags;
    UNICODE_STRING WindowTitle;
    UNICODE_STRING DesktopInfo;
    UNICODE_STRING ShellInfo;
    UNICODE_STRING RuntimeData;
    RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32];
    ULONG EnvironmentSize;
} RTL_USER_PROCESS_PARAMETERS,  *PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB_FREE_BLOCK
{
    struct _PEB_FREE_BLOCK *Next;
    ULONG Size;
} PEB_FREE_BLOCK,  *PPEB_FREE_BLOCK;
typedef struct _PEB
{
    UCHAR InheritedAddressSpace;
    UCHAR ReadImageFileExecOptions;
    UCHAR BeingDebugged;
    UCHAR BitField;
    /*ULONG ImageUsesLargePages: 1;
    ULONG IsProtectedProcess: 1;
    ULONG IsLegacyProcess: 1;
    ULONG IsImageDynamicallyRelocated: 1;
    ULONG SpareBits: 4;*/
    PVOID Mutant;
    PVOID ImageBaseAddress;
    PPEB_LDR_DATA Ldr;
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    PVOID SubSystemData;
    PVOID ProcessHeap;
    PRTL_CRITICAL_SECTION FastPebLock;
    PVOID AtlThunkSListPtr;
    PVOID IFEOKey;
    ULONG CrossProcessFlags;
    /*ULONG ProcessInJob: 1;
    ULONG ProcessInitializing: 1;
    ULONG ReservedBits0: 30;*/
    union
    {
        PVOID KernelCallbackTable;
        PVOID UserSharedInfoPtr;
    };
    ULONG SystemReserved[1];
    ULONG SpareUlong;
    PPEB_FREE_BLOCK FreeList;
    ULONG TlsExpansionCounter;
    PVOID TlsBitmap;
    ULONG TlsBitmapBits[2];
    PVOID ReadOnlySharedMemoryBase;
    PVOID HotpatchInformation;
    VOID **ReadOnlyStaticServerData;
    PVOID AnsiCodePageData;
    PVOID OemCodePageData;
    PVOID UnicodeCaseTableData;
    ULONG NumberOfProcessors;
    ULONG NtGlobalFlag;
    LARGE_INTEGER CriticalSectionTimeout;
    ULONG HeapSegmentReserve;
    ULONG HeapSegmentCommit;
    ULONG HeapDeCommitTotalFreeThreshold;
    ULONG HeapDeCommitFreeBlockThreshold;
    ULONG NumberOfHeaps;
    ULONG MaximumNumberOfHeaps;
    VOID **ProcessHeaps;
    PVOID GdiSharedHandleTable;
    PVOID ProcessStarterHelper;
    ULONG GdiDCAttributeList;
    PRTL_CRITICAL_SECTION LoaderLock;
    ULONG OSMajorVersion;
    ULONG OSMinorVersion;
    WORD OSBuildNumber;
    WORD OSCSDVersion;
    ULONG OSPlatformId;
    ULONG ImageSubsystem;
    ULONG ImageSubsystemMajorVersion;
    ULONG ImageSubsystemMinorVersion;
    ULONG ImageProcessAffinityMask;
    ULONG GdiHandleBuffer[34];
    PVOID PostProcessInitRoutine;
    PVOID TlsExpansionBitmap;
    ULONG TlsExpansionBitmapBits[32];
    ULONG SessionId;
    ULARGE_INTEGER AppCompatFlags;
    ULARGE_INTEGER AppCompatFlagsUser;
    PVOID pShimData;
    PVOID AppCompatInfo;
    UNICODE_STRING CSDVersion;
    void *ActivationContextData;
    void *ProcessAssemblyStorageMap;
    void *SystemDefaultActivationContextData;
    void *SystemAssemblyStorageMap;
    ULONG MinimumStackCommit;
    void *FlsCallback;
    LIST_ENTRY FlsListHead;
    PVOID FlsBitmap;
    ULONG FlsBitmapBits[4];
    ULONG FlsHighIndex;
    PVOID WerRegistrationData;
    PVOID WerShipAssertPtr;
}

//-------------------------------------------------------------------------

PEB,  *PPEB;
typedef VOID(NTAPI *PKNORMAL_ROUTINE)(PVOID Context, PVOID Argument1, PVOID Argument2);

#ifdef __cplusplus
template <typename T, unsigned n> struct APPENDBYTES
{
    typename T lead;
    char trail[n];
};
extern "C"
{
#endif 

    NTSYSAPI void NTAPI DbgBreakPoint(void);
    NTSYSAPI NTSTATUS NTAPI NtClose(HANDLE);
    NTSYSAPI NTSTATUS NTAPI NtQueryObject(HANDLE Handle, ULONG ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength);
    NTSYSAPI NTSTATUS NTAPI NtDuplicateObject(HANDLE SourceProcessHandle, HANDLE SourceHandle, HANDLE TargetProcessHandle, PHANDLE TargetHandle, ACCESS_MASK DesiredAccess, BOOLEAN InheritHandle, ULONG Options);
    NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(HANDLE Handle, BOOLEAN Alertable, PLARGE_INTEGER Timeout);
    NTSYSAPI NTSTATUS NTAPI NtReleaseMutant(HANDLE MutantHandle, PULONG PreviousState);
    NTSYSAPI NTSTATUS NTAPI NtQueueApcThread(HANDLE ThreadHandle, PKNORMAL_ROUTINE ApcRoutine, PVOID Context, PVOID Argument1, PVOID Argument2);
    NTSYSAPI NTSTATUS NTAPI NtResumeThread(HANDLE ThreadHandle, PULONG SuspendCount);
    NTSYSAPI NTSTATUS NTAPI NtOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId);
    NTSYSAPI NTSTATUS NTAPI NtSetInformationProcess(HANDLE ProcessHandle, ULONG ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength);
    NTSYSAPI NTSTATUS NTAPI NtQueryInformationProcess(HANDLE ProcessHandle, ULONG ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
    NTSYSAPI NTSTATUS NTAPI NtAllocateVirtualMemory(HANDLE ProcessHandle, PVOID *BaseAddress, ULONG ZeroBits, size_t *AllocationSize, ULONG AllocationType, ULONG Protect);
    NTSYSAPI NTSTATUS NTAPI NtProtectVirtualMemory(HANDLE ProcessHandle, void **BaseAddress, size_t *ProtectSize, ULONG NewProtect, PULONG OldProtect);
    NTSYSAPI NTSTATUS NTAPI NtFlushInstructionCache(HANDLE ProcessHandle, void *BaseAddress, size_t FlushSize);
    NTSYSAPI NTSTATUS NTAPI NtQueryVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, MEMORY_INFORMATION_CLASS MemoryInformationClass, PVOID MemoryInformation, ULONG MemoryInformationLength, PULONG ReturnLength);
    NTSYSAPI NTSTATUS NTAPI NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PFILE_FULL_EA_INFORMATION EaBuffer, ULONG EaLength);
    NTSYSAPI NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key);
    NTSYSAPI NTSTATUS NTAPI NtWriteFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key);
    NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG IoControlCode, PVOID InputBuffer, SIZE_T InputBufferLength, PVOID OutputBuffer, SIZE_T OutputBufferLength);
    NTSYSAPI NTSTATUS NTAPI NtCreateSection(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle);
    NTSYSAPI NTSTATUS NTAPI NtOpenSection(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);
    NTSYSAPI NTSTATUS NTAPI NtMapViewOfSection(HANDLE SectionHandle, HANDLE ProcessHandle, PVOID *BaseAddress, ULONG_PTR ZeroBits, SIZE_T CommitSize, PLARGE_INTEGER SectionOffset, PSIZE_T ViewSize, SECTION_INHERIT InheritDisposition, ULONG AllocationType, ULONG Win32Protect);
    NTSYSAPI NTSTATUS NTAPI NtUnmapViewOfSection(HANDLE ProcessHandle, PVOID BaseAddress);
    NTSYSAPI void NTAPI RtlFreeAnsiString(PANSI_STRING);
    NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString);
    NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString);
    NTSYSAPI NTSTATUS NTAPI RtlCreateUserThread(HANDLE ProcessHandle, PSECURITY_DESCRIPTOR SecurityDescriptor, BOOLEAN CreateSuspended, ULONG StackZeroBits, PULONG StackReserved, PULONG StackCommit, PVOID StartAddress, PVOID StartParameter, PHANDLE ThreadHandle, PCLIENT_ID ClientID);
    NTSYSAPI void *NTAPI RtlCreateHeap(ULONG Flags, void *HeapBase, size_t ReserveSize, size_t CommitSize, void *Lock, void *Parameter);
    NTSYSAPI void *NTAPI RtlDestroyHeap(void *HeapHandle);
    NTSYSAPI void *NTAPI RtlAllocateHeap(void *HeapHandle, ULONG Flags, size_t Size);
    NTSYSAPI int NTAPI RtlFreeHeap(void *HeapHandle, ULONG Flags, void *HeapBase);
    NTSYSAPI NTSTATUS NTAPI LdrLoadDll(PWCHAR PathToFile, ULONG Flags, PUNICODE_STRING ModuleFileName, HMODULE *ModuleHandle);
    NTSYSAPI NTSTATUS NTAPI LdrGetDllHandle(wchar_t *Path, void *Reserved, PUNICODE_STRING FileName, HMODULE *ImageBase);
    NTSYSAPI NTSTATUS NTAPI LdrGetProcedureAddress(HMODULE ModuleHandle, PANSI_STRING FunctionName, WORD Oridinal, PVOID *FunctionAddress);
    int WINAPI reportln(char *str);
    int WINAPI reportlnw(wchar_t *str);
#ifdef __cplusplus
}

//-------------------------------------------------------------------------

#endif 
#endif 
#ifdef _M_X64
#define printdec(Value){char __Buffer[64];_i64toa((long long)(Value),__Buffer,10);reportln(__Buffer);}
#define printhex(Value){char __Buffer[64];_i64toa((long long)(Value),__Buffer,16);reportln(__Buffer);}
#define outhex(Value){char __Buffer[64];_i64toa((long long)(Value),__Buffer,16);OutputDebugStringA(__Buffer);}
#else 
#define printdec(Value){char __Buffer[32];_ltoa((long)(Value),__Buffer,10);reportln(__Buffer);}
#define printhex(Value){char __Buffer[32];_ltoa((long)(Value),__Buffer,16);reportln(__Buffer);}
#define outhex(Value){char __Buffer[32];_ltoa((long)(Value),__Buffer,16);OutputDebugStringA(__Buffer);}
#endif
